class ExplosionObject extends UTProj_LinkPlasma
	placeable;

var() const protected int   MaxBounceCount;

var protected transient int BounceCount;

var() protected float   VelocityDampingFactor;

var() protected float   Bounciness;

var() protected float   StopSimulatingVelocityThreshhold;

event Init(Vector Direction)
{
	super.Init(Direction);
}

simulated function bool ShouldBounce(Actor Touched, vector HitNormal, optional PrimitiveComponent HitComponent)
{
    if( (Touched == None) || (Base != None) )
    {
        return FALSE;
    }

    // cannot collide with instigator until it has bounced once
    // also don't allow projectiles to collide while spawning on clients
    // because if that were accurate, the projectile would've been destroyed immediately on the server
    // and therefore it wouldn't have been replicated to the client
    if ((Touched == Instigator || (Role < ROLE_Authority && !bBegunPlay))/* && BounceCount == 0*/)
    {
        return FALSE;
    }

    if( Touched.bWorldGeometry || Touched.bBlockActors )
    {
        return TRUE;
    }

    return FALSE;
}

simulated function Bounce(Vector HitLocation, Vector HitNormal, Actor Other)
{
    if( !bBounce || BounceCount >= MaxBounceCount )
    {
        StopBounce(HitNormal);
        return;
    }
    BounceCount++;

    // bounce off wall with damping
    Velocity -= (1.f + Bounciness) * HitNormal * (Velocity Dot HitNormal);
    Velocity *= VelocityDampingFactor;

    // should we stop simulating?
    if( VSize(Velocity) < StopSimulatingVelocityThreshhold )
    {
        StopBounce(HitNormal);
    }
}

simulated function HandleCollision( Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal )
{
	//`log(self@"** hit!"@Other@OtherComp@HitNormal@HitLocation);
    if( Other != None && ShouldBounce(Other, HitNormal) && Physics == PHYS_Projectile )
    {
        // a bit of a hack, massage data for pawns
        if ( (Pawn(Other) != None) && (SkeletalMeshComponent(OtherComp) != None) )
        {
            HitNormal = HitLocation - Other.Location;
            HitNormal.Z = 0.f;
            HitNormal = Normal(HitNormal);
        }
        Bounce(HitLocation, HitNormal, Other);
    }
}

simulated function StopBounce(vector HitNormal)
{
    bBounce = FALSE;
    if (Role == ROLE_Authority )
    {
        Explode(Location, HitNormal);
    }
}


simulated singular event Touch( Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal )
{
    // Ignore touches on fluid surface or physics volumes
    if(FluidSurfaceActor(Other) != None || PhysicsVolume(Other) != None)
    {
        return;
    }

    HandleCollision( Other, OtherComp, HitLocation, HitNormal );
}

simulated function HitWall( vector HitNormal, Actor Wall, PrimitiveComponent WallComp )
{
    HandleCollision( Wall, WallComp, Location, HitNormal );
}

DefaultProperties
{
	MaxBounceCount=3
	StopSimulatingVelocityThreshhold=40
	Bounciness=0.5
	VelocityDampingFactor=0.9
	ProjFlightTemplate=ParticleSystem'WP_RocketLauncher.Effects.P_WP_RocketLauncher_Smoke_Trail'
	ProjExplosionTemplate=ParticleSystem'WP_RocketLauncher.Effects.P_WP_RocketLauncher_RocketExplosion'

	bBounce=true
	Speed=500
	Begin Object Class=SkeletalMeshComponent Name=ESkeletalMeshComponent
		SkeletalMesh=SkeletalMesh'KismetGame_Assets.Anims.SK_Jazz'
		BlockRigidBody=TRUE
		bUpdateSkelWhenNotRendered=false
		Translation=(Z=0.0)
		Scale=0.5f
	End Object
	Components.Add(ESkeletalMeshComponent)
}
